// SPDX-FileCopyrightText: Copyright 2025-2025 深圳市同心圆网络有限公司
// SPDX-License-Identifier: Apache-2.0

package roadmap_member_api_serv

import (
	"context"
	"time"

	"gitcode.com/lvupclub/lvup-api/dao"
	"gitcode.com/lvupclub/lvup-api/dao/roadmap_dao"
	"gitcode.com/lvupclub/lvup-api/dao/user_dao"
	"gitcode.com/lvupclub/lvup-api/notice_serv"
	"gitcode.com/lvupclub/proto-gen-go.git/src/notices/notices_user"
	"gitcode.com/lvupclub/proto-gen-go.git/src/roadmap_member_api"
	"gitcode.com/lvupclub/proto-gen-go.git/src/user_msg_type_api"
	"github.com/google/uuid"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/types/known/anypb"
)

func (apiImpl *RoadmapMemberApiImpl) GetMyState(ctx context.Context, req *roadmap_member_api.GetMyStateRequest) (*roadmap_member_api.GetMyStateResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_member_api.GetMyStateResponse{
			Code:   roadmap_member_api.GetMyStateResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	exist, err := roadmap_dao.RoadmapMemberDao.Exist(ctx, req.RoadmapId, sessItem.UserId)
	if err != nil {
		return nil, err
	}
	if exist {
		return &roadmap_member_api.GetMyStateResponse{
			Code:    roadmap_member_api.GetMyStateResponse_CODE_OK,
			MyState: roadmap_member_api.MY_STATE_MY_STATE_IS_MEMBER,
		}, nil
	}
	exist, err = roadmap_dao.ApplyInfoDao.Exist(ctx, req.RoadmapId, sessItem.UserId)
	if err != nil {
		return nil, err
	}
	if exist {
		return &roadmap_member_api.GetMyStateResponse{
			Code:    roadmap_member_api.GetMyStateResponse_CODE_OK,
			MyState: roadmap_member_api.MY_STATE_MY_STATE_IN_APPLY,
		}, nil
	}

	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_member_api.GetMyStateResponse{
			Code:   roadmap_member_api.GetMyStateResponse_CODE_NO_ROADMAP,
			ErrMsg: "成长路线图不存在",
		}, nil
	}
	if roadmapItem.OwnerUserId == sessItem.UserId {
		return &roadmap_member_api.GetMyStateResponse{
			Code:    roadmap_member_api.GetMyStateResponse_CODE_OK,
			MyState: roadmap_member_api.MY_STATE_MY_STATE_IS_OWNER,
		}, nil
	}

	if roadmapItem.BasicInfo.EnableJoinApply {
		return &roadmap_member_api.GetMyStateResponse{
			Code:    roadmap_member_api.GetMyStateResponse_CODE_OK,
			MyState: roadmap_member_api.MY_STATE_MY_STATE_CAN_APPLY,
		}, nil
	} else {
		return &roadmap_member_api.GetMyStateResponse{
			Code:    roadmap_member_api.GetMyStateResponse_CODE_OK,
			MyState: roadmap_member_api.MY_STATE_MY_STATE_NO_PERM,
		}, nil
	}
}

func (apiImpl *RoadmapMemberApiImpl) ApplyJoin(ctx context.Context, req *roadmap_member_api.ApplyJoinRequest) (*roadmap_member_api.ApplyJoinResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_member_api.ApplyJoinResponse{
			Code:   roadmap_member_api.ApplyJoinResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	userItem, err := user_dao.UserInfoDao.GetById(ctx, sessItem.UserId)
	if err != nil {
		return nil, err
	}
	exist, err := roadmap_dao.RoadmapMemberDao.Exist(ctx, req.RoadmapId, sessItem.UserId)
	if err != nil {
		return nil, err
	}
	if exist {
		return &roadmap_member_api.ApplyJoinResponse{
			Code: roadmap_member_api.ApplyJoinResponse_CODE_OK,
		}, nil
	}
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_member_api.ApplyJoinResponse{
			Code:   roadmap_member_api.ApplyJoinResponse_CODE_NO_ROADMAP,
			ErrMsg: "成长路线图不存在",
		}, nil
	}
	if roadmapItem.OwnerUserId == sessItem.UserId {
		return &roadmap_member_api.ApplyJoinResponse{
			Code: roadmap_member_api.ApplyJoinResponse_CODE_OK,
		}, nil
	}
	if !roadmapItem.BasicInfo.EnableJoinApply {
		return &roadmap_member_api.ApplyJoinResponse{
			Code:   roadmap_member_api.ApplyJoinResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有缺陷",
		}, nil
	}
	srcMsg, err := anypb.New(&user_msg_type_api.ApplyJoinRoadmap{
		RoadmapId:   roadmapItem.RoadmapId,
		RoadmapName: roadmapItem.BasicInfo.Name,
	})
	if err != nil {
		return nil, err
	}
	srcMsgData, err := proto.Marshal(srcMsg)
	if err != nil {
		return nil, err
	}
	destMsg, err := anypb.New(&user_msg_type_api.RecvApplyJoinRoadmap{
		RoadmapId:            roadmapItem.RoadmapId,
		RoadmapName:          roadmapItem.BasicInfo.Name,
		ApplyUserId:          sessItem.UserId,
		ApplyUserDisplayName: userItem.BasicInfo.DisplayName,
		ApplyUserLogoUri:     userItem.BasicInfo.LogoUri,
	})
	if err != nil {
		return nil, err
	}
	destMsgData, err := proto.Marshal(destMsg)
	if err != nil {
		return nil, err
	}

	nowTime := time.Now().UnixMilli()

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
		err = roadmap_dao.ApplyInfoDao.Insert(sessCtx, &roadmap_dao.ApplyInfoDbItem{
			RoadmapId: req.RoadmapId,
			UserId:    sessItem.UserId,
			TimeStamp: nowTime,
		})
		if err != nil {
			return nil, err
		}
		//发送申请消息(发送方)
		err = user_dao.UserMsgInfoDao.Insert(sessCtx, &user_dao.UserMsgInfoDbItem{
			MsgId:     uuid.NewString(),
			UserId:    sessItem.UserId,
			MsgData:   srcMsgData,
			TimeStamp: nowTime,
			HasRead:   false,
		})
		if err != nil {
			return nil, err
		}
		//发送申请消息(接收方)
		err = user_dao.UserMsgInfoDao.Insert(sessCtx, &user_dao.UserMsgInfoDbItem{
			MsgId:     uuid.NewString(),
			UserId:    roadmapItem.OwnerUserId,
			MsgData:   destMsgData,
			TimeStamp: nowTime,
			HasRead:   false,
		})
		if err != nil {
			return nil, err
		}
		return &roadmap_member_api.ApplyJoinResponse{
			Code: roadmap_member_api.ApplyJoinResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	//发送通知
	go notice_serv.PublishToUser(sessItem.UserId, &notices_user.NewMsgNotice{})
	go notice_serv.PublishToUser(roadmapItem.OwnerUserId, &notices_user.NewMsgNotice{})
	return ret.(*roadmap_member_api.ApplyJoinResponse), nil
}

func (apiImpl *RoadmapMemberApiImpl) AllowJoin(ctx context.Context, req *roadmap_member_api.AllowJoinRequest) (*roadmap_member_api.AllowJoinResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_member_api.AllowJoinResponse{
			Code:   roadmap_member_api.AllowJoinResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	//检查是否是路线图owner
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_member_api.AllowJoinResponse{
			Code:   roadmap_member_api.AllowJoinResponse_CODE_NO_ROADMAP,
			ErrMsg: "成长路线图不存在",
		}, nil
	}
	if roadmapItem.OwnerUserId != sessItem.UserId {
		return &roadmap_member_api.AllowJoinResponse{
			Code:   roadmap_member_api.AllowJoinResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	//检查是否已经是成员了
	exist, err := roadmap_dao.RoadmapMemberDao.Exist(ctx, req.RoadmapId, req.ApplyUserId)
	if err != nil {
		return nil, err
	}
	if exist {
		return &roadmap_member_api.AllowJoinResponse{
			Code: roadmap_member_api.AllowJoinResponse_CODE_OK,
		}, nil
	}
	//检查请求是否存在
	exist, err = roadmap_dao.ApplyInfoDao.Exist(ctx, req.RoadmapId, req.ApplyUserId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &roadmap_member_api.AllowJoinResponse{
			Code:   roadmap_member_api.AllowJoinResponse_CODE_NO_APPLY_USER,
			ErrMsg: "申请加入记录不存在",
		}, nil
	}

	msg, err := anypb.New(&user_msg_type_api.AllowJoinRoadmap{
		RoadmapId:   req.RoadmapId,
		RoadmapName: roadmapItem.BasicInfo.Name,
	})
	if err != nil {
		return nil, err
	}
	msgData, err := proto.Marshal(msg)
	if err != nil {
		return nil, err
	}
	nowTime := time.Now().UnixMilli()

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
		err = roadmap_dao.ApplyInfoDao.Remove(sessCtx, req.RoadmapId, req.ApplyUserId)
		if err != nil {
			return nil, err
		}
		planCount, err := roadmap_dao.PlanInfoDao.Count(sessCtx, req.RoadmapId, req.ApplyUserId)
		if err != nil {
			return nil, err
		}
		err = roadmap_dao.RoadmapMemberDao.Insert(sessCtx, &roadmap_dao.MemberInfoDbItem{
			RoadmapId:    req.RoadmapId,
			MemberUserId: req.ApplyUserId,
			JoinTime:     nowTime,
			PlanCount:    planCount,
		})
		if err != nil {
			return nil, err
		}
		err = user_dao.UserMsgInfoDao.Insert(sessCtx, &user_dao.UserMsgInfoDbItem{
			MsgId:     uuid.NewString(),
			UserId:    req.ApplyUserId,
			MsgData:   msgData,
			TimeStamp: nowTime,
			HasRead:   false,
		})
		if err != nil {
			return nil, err
		}
		return &roadmap_member_api.AllowJoinResponse{
			Code: roadmap_member_api.AllowJoinResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	//发送通知
	go notice_serv.PublishToUser(req.ApplyUserId, &notices_user.NewMsgNotice{})
	return ret.(*roadmap_member_api.AllowJoinResponse), nil
}
